#ifndef _TCPSOCKET_
#define _TCPSOCKET_

#include <arpa/inet.h>
#include <iostream>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
// #include "Protocol.hpp"
#include "Log.hpp"
#include <cstring>

class MySocket
{
public:
    // 关于参数设定， 一般的：
    // int *it 一般为输出型参数
    // const int& it; 一般为输入型参数
    // int & it; 可输入，可输出
    MySocket()
    {
    }

    int _socket_set()
    {
        int _socket_ = socket(AF_INET, SOCK_STREAM, 0);
        if (!_socket_)
        {
            Logmessage(FATIL, "socket fatil%d %s", errno, strerror(errno));
            exit(0);
        }
        return _socket_;
    }

    // 目前设置默认绑定
    void bind_set(int listen_socket_, uint16_t port, const std::string &ip = "") // const struct sockaddr_in& goal_ = _host
    {
        if (!listen_socket_)
            perror("lack listen_socket");

        struct sockaddr_in _host;
        bzero(&_host, sizeof _host);
        _host.sin_family = AF_INET;
        _host.sin_port = htons(port);
        _host.sin_addr.s_addr = ip.empty() ? INADDR_ANY : inet_addr(ip.c_str());

        if (bind(listen_socket_, (sockaddr *)&_host, sizeof _host) < 0)
        {
            Logmessage(FATIL, "bind fatil%d %s", errno, strerror(errno));
            exit(2);
        }
    }

    bool listen_run(int listen_socket_)
    {
        if (listen(listen_socket_, 20) < 0)
        {
            Logmessage(FATIL, "listen fatil %d %s", errno, strerror(errno));
            exit(3);
        }
        Logmessage(NOWAIN, "SERVICE SUCCESS %d %s", errno, strerror(errno));
        return 1;
    }

    int accept_run(int listen_socket_, sockaddr_in *send_, uint16_t *send_port)
    {
        bzero(send_, sizeof *send_);
        socklen_t len = sizeof *send_;
        // accept会等待请求方申请，会处于阻塞状态
        int actual_socket = accept(listen_socket_, (sockaddr *)send_, &len);
        if (actual_socket)
        {
            *send_port = ntohs(send_->sin_port);
        }
        return actual_socket;
    }

    bool Connect(int cline_socket, int port, std::string ip)
    {
        struct sockaddr_in goal_service;
        bzero(&goal_service, sizeof goal_service);
        goal_service.sin_family = AF_INET;
        goal_service.sin_port = htons(port);
        goal_service.sin_addr.s_addr = inet_addr(ip.c_str());
        // 2.建立连接
        if (connect(cline_socket, (sockaddr *)&goal_service, sizeof goal_service) < 0)
        {
            Logmessage(FATIL, "cline connect fail %d %s", errno, strerror(errno));
            exit(1);
        }
        else
        {
            return 1;
        }
    }

    void Send(int cline_socket, const std::string &message)
    {
        if (send(cline_socket, message.c_str(), message.size(), 0) < 0)
            Logmessage(FATIL, "send fail");
    }

    bool Recv(int socket, char *buff, size_t buff_lenth)
    {
        ssize_t ret = recv(socket, buff, buff_lenth, 0);
        if (ret)
        {
            buff[ret] = 0;
            return 1;
        }else
        {
            return 0;
        }
    }

};

#endif
